# frozen_string_literal: true

require_relative '../../../../spec_helper'

describe Wpxf::IntegerOption do
  let(:attrs) { { name: 'test', desc: 'desc' } }
  let(:subject) { Wpxf::IntegerOption.new(attrs) }

  describe '#new' do
    context 'if a :min option is in the attributes' do
      let(:attrs) { { name: 'test', desc: 'desc', min: 5 } }
      it 'sets the min attribute to match the value specified' do
        expect(subject.min).to eq 5
      end
    end

    context 'if a :min option is in the attributes' do
      let(:attrs) { { name: 'test', desc: 'desc', max: 10 } }
      it 'sets the min attribute to match the value specified' do
        expect(subject.max).to eq 10
      end
    end
  end

  describe '#normalize' do
    it 'returns the integer equivalent if a hex literal is used as the value' do
      expect(subject.normalize('0xFF')).to eq 255
    end

    it 'returns the integer value of the value specified' do
      expect(subject.normalize('255')).to eq 255
      expect(subject.normalize('')).to eq 0
    end
  end

  describe '#valid_integer?' do
    it 'returns true if the value is a valid integer or hex literal' do
      ['0xFF', '255', 255].each do |v|
        expect(subject.valid_integer?(v)).to be true
      end
    end

    it 'returns false if the value isn\'t a valid integer or hex literal' do
      ['invalid', 'value', false].each do |v|
        expect(subject.valid_integer?(v)).to be false
      end
    end
  end

  describe '#meets_min_requirement' do
    it 'returns true when the min value hasn\'t been specified' do
      expect(subject.meets_min_requirement?(0))
    end

    context 'when the min has been specified' do
      let(:attrs) { { name: 'test', desc: 'desc', min: 5 } }

      it 'returns true if the value >= the min value' do
        [5, 10].each do |v|
          expect(subject.meets_min_requirement?(v)).to be true
        end
      end

      it 'returns false if the value < the min value' do
        expect(subject.meets_min_requirement?(4)).to be false
      end
    end
  end

  describe '#meets_max_requirement' do
    it 'returns true when the max value hasn\'t been specified' do
      expect(subject.meets_max_requirement?(0))
    end

    context 'when the max has been specified' do
      let(:attrs) { { name: 'test', desc: 'desc', max: 5 } }

      it 'returns true if the value <= the max value' do
        [5, 1].each do |v|
          expect(subject.meets_max_requirement?(v)).to be true
        end
      end

      it 'returns false if the value > the max value' do
        expect(subject.meets_max_requirement?(6)).to be false
      end
    end
  end

  describe '#valid?' do
    it 'returns false if the value isn\'t a valid integer' do
      expect(subject.valid?('invalid')).to be false
    end

    context 'when a min is specified' do
      let(:attrs) { { name: 'test', desc: 'desc', min: 5 } }
      it 'returns false if the value doesn\'t meet the min requirement' do
        expect(subject.valid?(3)).to be false
      end
    end

    context 'when a max is specified' do
      let(:attrs) { { name: 'test', desc: 'desc', max: 5 } }
      it 'returns false if the value doesn\'t meet the max requirement' do
        expect(subject.valid?(8)).to be false
      end
    end
  end
end
